package foundation.common.util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zkoss.zul.impl.api.InputElement;

import foundation.web.flow.AbstractNavigationComposer;
import foundation.web.flow.FlowStepStateHolder;
import foundation.web.flow.ValueState;
/**
 * This class holds all attribute values for a given composer
 * in order to set them in the future
 * @author fgarcia
 *
 */
public class ComposerStateHolder implements FlowStepStateHolder {

	private static final Log log = LogFactory.getLog(ComposerStateHolder.class);
	
	private static Class<InputElement> inputClass = InputElement.class;
	
	private String composerName ="";
	Map<String, Object> values = new HashMap<String, Object>();


	public Object getValueOf(String inputName) {
		return values.get(inputName);
	}

	/**
	 * Set the hold values to the composer
	 * @param composer composer to restore 
	 * @throws Exception
	 */
//	public void setState(AbstractNavigationComposer composer) {
//		this.restoreField(composer,values);
//	}
	
//	private void restoreField(GenericForwardComposer composer,Map<String, Object> valuesOrigin){
//		try{
//		for (Entry<String, Object> entry : valuesOrigin.entrySet()) {
//
//			String attrName = entry.getKey();
//
//			//the new Field = field to restore
//			Field fieldToRestore = composer.getClass().getField(attrName);
//			Object objectToRestore = fieldToRestore.get(composer);
//			
//			//In valueState there are the origin field and value
//			ValueState valueStateOrigin = (ValueState)entry.getValue();
//			Object value= valueStateOrigin.getValue();
//			if(value!=null){
//				if(value instanceof Tab){
//					Tab inputElemToRestore = (Tab)objectToRestore;
//					Tab inputElemOrgin = (Tab)valueStateOrigin.getValue();
//					inputElemToRestore.setSelected(inputElemOrgin.isSelected());
//					inputElemToRestore.setVisible(inputElemOrgin.isVisible());
//					fieldToRestore.set(composer,inputElemToRestore);												
//				}
//				else if(value instanceof Paging){
//					Paging inputElemToRestore = (Paging)objectToRestore;
//					Paging inputElemOrgin = (Paging)valueStateOrigin.getValue();
//					inputElemToRestore.setTotalSize(inputElemOrgin.getTotalSize());
//					inputElemToRestore.setPageSize(inputElemOrgin.getPageSize());
//					inputElemToRestore.setPageIncrement(inputElemOrgin.getPageIncrement());
//					inputElemToRestore.setActivePage(inputElemOrgin.getActivePage());				
//					fieldToRestore.set(composer,inputElemToRestore);												
//				}
//				else if(value instanceof GridComposer){
//					GridComposer inputElemToRestore = (GridComposer)objectToRestore;
//					GridComposer inputElemOrgin = (GridComposer)valueStateOrigin.getValue();
//					if(inputElemOrgin.getMold().equals("paging")){
//						inputElemToRestore.setActivePageCustom(inputElemOrgin.getActivePage());
//						fieldToRestore.set(composer,inputElemToRestore);	
//					}											
//				}
//				else if(value instanceof FiltroBusquedaMacro){
//					FiltroBusquedaMacro inputElemToRestore = (FiltroBusquedaMacro)objectToRestore;
//					FiltroBusquedaMacro inputElemOrgin = (FiltroBusquedaMacro)valueStateOrigin.getValue();
//					Object selectObject =inputElemOrgin.getSelectedObject();
//					if(selectObject!=null){
//						inputElemToRestore.setComposer(composer);
//						inputElemToRestore.selectedObject(inputElemOrgin.getSelectedObject(),HibernateProxyHelper.getClassWithoutInitializingProxy(inputElemOrgin.getSelectedObject()));
//						fieldToRestore.set(composer,inputElemToRestore);	
//					}								
//				}
//				else if(value instanceof ComboBoxEnum){
//					ComboBoxEnum inputElemToRestore = (ComboBoxEnum)objectToRestore;
//					ComboBoxEnum inputElemOrgin = (ComboBoxEnum)valueStateOrigin.getValue();
//					Object model = inputElemOrgin.getModel();
//					inputElemToRestore.setLabelFirstElement(inputElemOrgin.getLabelFirstElement());
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					inputElemToRestore.setModel(inputElemOrgin.getModel());				
//					if(inputElemOrgin.getSelectedItemApi()!=null)
//						inputElemToRestore.setObjectSelect(inputElemOrgin.getSelectedItemApi().getValue());
//					else
//						inputElemToRestore.setObjectSelect(inputElemOrgin.getObjectSelect());
//					inputElemToRestore.setNotSetterValueFirstElem(true);
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof ComboBoxEntity){
//					ComboBoxEntity inputElemToRestore = (ComboBoxEntity)objectToRestore;
//					ComboBoxEntity inputElemOrgin = (ComboBoxEntity)valueStateOrigin.getValue();
//					inputElemToRestore.setLabelFirstElement(inputElemOrgin.getLabelFirstElement());
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					if(inputElemOrgin.getSelectedItemApi()!=null)
//						inputElemToRestore.setObjectSelect(inputElemOrgin.getSelectedItemApi().getValue());
//					if(inputElemOrgin.getObjectSelect()!=null)
//						inputElemToRestore.setObjectSelect(inputElemOrgin.getObjectSelect());
//					inputElemToRestore.setNotSetterValueFirstElem(true);
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Combobox){
//					Combobox inputElemToRestore = (Combobox)objectToRestore;
//					Combobox inputElemOrgin = (Combobox)valueStateOrigin.getValue();				
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Checkbox){
//					Checkbox inputElemToRestore = (Checkbox)objectToRestore;
//					Checkbox inputElemOrgin = (Checkbox)valueStateOrigin.getValue();		
//					inputElemToRestore.setChecked(inputElemOrgin.isChecked());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Datebox){
//					Datebox inputElemToRestore = (Datebox)objectToRestore;
//					Datebox inputElemOrgin = (Datebox)valueStateOrigin.getValue();		
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Doublebox){
//					Doublebox inputElemToRestore = (Doublebox)objectToRestore;
//					Doublebox inputElemOrgin = (Doublebox)valueStateOrigin.getValue();		
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Longbox){
//					Longbox inputElemToRestore = (Longbox)objectToRestore;
//					Longbox inputElemOrgin = (Longbox)valueStateOrigin.getValue();		
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Intbox){
//					Intbox inputElemToRestore = (Intbox)objectToRestore;
//					Intbox inputElemOrgin = (Intbox)valueStateOrigin.getValue();		
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}			
//				else if(value instanceof Textbox){
//					Textbox inputElemToRestore = (Textbox)objectToRestore;
//					Textbox inputElemOrgin = (Textbox)valueStateOrigin.getValue();		
//					inputElemToRestore.setValue(inputElemOrgin.getValue());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Div){
//					Div inputElemToRestore = (Div)objectToRestore;
//					Div inputElemOrgin = (Div)valueStateOrigin.getValue();		
//					inputElemToRestore.setVisible(inputElemOrgin.isVisible());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof Button){
//					Button inputElemToRestore = (Button)objectToRestore;
//					Button inputElemOrgin = (Button)valueStateOrigin.getValue();		
//					inputElemToRestore.setVisible(inputElemOrgin.isVisible());
//					fieldToRestore.set(composer,inputElemToRestore);
//				}
//				else if(value instanceof AbstractBaseMacro){
//					AbstractBaseMacro inputElemToRestore = (AbstractBaseMacro)objectToRestore;		
//					AbstractBaseMacro inputElemOrgin = (AbstractBaseMacro)valueStateOrigin.getValue();
//					Map<String, Object> valuesOriginInput = this.getValuesToSave(inputElemOrgin.getComposer());
//					this.restoreField(inputElemToRestore.getComposer(),valuesOriginInput);
//				}
//				else if(value instanceof String && (value.equals(CommonWebUtil.CALLBACK_ARGUMENT) || value.equals(CommonWebUtil.OBJECT_TO_EDIT_ARGUMENT))){
//					//fieldToRestore.set(composer,value);
//				}
//				else {				
//					fieldToRestore.set(composer,value);
//				}				
//			}
//
//		}		
//		
//		//now it'll call to the methods setter in the composer	
//		//composer.callMethods();
//		Class objectClass = composer.getClass();
//		objectClass.getMethod("callMethods").invoke(composer);		
//		}
//		catch (Exception e) {
//			log.error(e.getMessage());
//		}
//	}

	/**
	 * Saves a Composer attributes state
	 * @param composer composer to save its statue
	 */
	public void getState(AbstractNavigationComposer composer) {	
		values =this.getValuesToSave(composer);
		composerName=composer!=null?composer.getClass().getSimpleName():"";
	}
	
	
	private Map<String, Object> getValuesToSave(Object object){
		Map<String, Object> valuesToSave =  new HashMap<String, Object>();
		try {		
			//TODO validar si con todos los fields public es suficiente				
			//the next sentences get all "public" field of the composer			
			Field[] fields = object.getClass().getFields();
			for (Field field : fields) {
					ValueState valueState = new ValueState();
					valueState.setField(field);
					valueState.setValue(field.get(object));
					valuesToSave.put(field.getName(), valueState);							
			}
		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			log.error(e.getMessage());		
		}
		return valuesToSave;
		}

	public String getComposerName() {
		return composerName;
	}

	public void setComposerName(String composerName) {
		this.composerName = composerName;
	}

	
	
}
